local jwt_parser = require "kong.plugins.jwt.jwt_parser"
local utils = require('kong.plugins.kong-ucenter-auth.utils')
local redis = require "kong.plugins.kong-ucenter-auth.redis-util"

local UCenterAuth = {}

UCenterAuth.PRIORITY = 1000

function UCenterAuth:new()
end

function UCenterAuth:access(conf)
    --- 判断Header中是否带有认证信息
    local auth_header = ngx.var.http_Authorization
    if auth_header == nil then
        ngx.log(ngx.WARN, '未提供JWT认证参数')
        ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end

    --- 解析JWT Token
    local _, _, token = string.find(auth_header, 'Bearer%s+(.+)')
    if token == nil then
        ngx.log(ngx.WARN, '未找到JWT令牌')
        ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end

    --- 检查Redis中是否存在Token
    local client = redis:new({
        host = conf.redis_address,
        port = conf.redis_port,
        db_index = 0,
        password = conf.redis_password,
        timeout = 1000,
        keepalive = 60000,
        pool_size = 100
    })

    local entity, err = client:get(token)
    if err then
        ngx.log(ngx.ERR, '访问Redis失败:' .. tostring(err))
        ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end
    local jwt_obj, err = jwt_parser:new(entity)
    if err then
        ngx.log(ngx.ERR, '令牌解析失败:' .. tostring(err))
        ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end

    --- 检查JWT令牌是否能够解析
    if jwt_obj.claims == nil then
        ngx.log(ngx.ERR, 'JWT令牌信息不完整')
        ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end

    --- 检查访问的URL是否具备权限
    local permission = utils.split(jwt_obj.claims.permissions, ',')

    if utils.has_value(permission, ngx.var.uri) == false then
        ngx.log(ngx.WARN, '用户无该路由的权限')
        ngx.exit(ngx.HTTP_UNAUTHORIZED)
    end

    --- 获取Token中的附加信息
    kong.service.request.set_header("userid", jwt_obj.claims.user_id)
    kong.service.request.set_header("alias", jwt_obj.claims.alias)
end

function UCenterAuth:header_filter(conf)

end

function UCenterAuth:body_filter(conf)
end
return UCenterAuth
